---
sidebar_position: 2.2
description: SpringBootAdmin微服务应用监控
---
import Highlight from "@site/src/components/Highlight";
import P from "@site/src/components/P";

# SpringBootAdmin微服务应用监控

## SpringBootActuator
#### ActuatorEndpoints(端点)
* Endpoints 是 Actuator 的核心部分，它用来监视应用程序及交互；SpringBoot Actuator 内置了很多 Endpoints,并支持扩展。
#### SpringBoot Actuator提供的原生端点有三类
* <Highlight color={'red'}>应用配置类</Highlight>：自动配置信息、Spring Bean 信息、yml 文件信息、环境信息等。
* <Highlight color={'red'}>度量指标类</Highlight>：主要是运行期间的动态信息，比如堆栈、健康指标、metrics信息等等。
* <Highlight color={'red'}>操作控制类</Highlight>：主要是只shutdown，用户可以发送一个请求将应用的监控功能关闭。

:::tip
<P>所谓的端点就是http接口，这些接口都是rest类型，返回的都是json数据，所以需要我们自己去实现对json数据的解析和观测。不仅麻烦而且耗时，所以 SpringBootAdmin 出现了。</P>

<P>SpringBootAdmin 通过调用 SpringBootActuator端点并使用VUE框架以可视化的图形去呈现这些端点的监控数据，实时的告诉我们应用的健康状态，目前已经被广泛的应用于SpringBoot单体应用和SpringCloud微服务应用中。</P>
:::

## 搭建SpringBootAdmin监控服务器
#### 添加SpringBootAdminStarter自动配置依赖
* spring-boot-admin-server：Server端
* spring-boot-admin-server-ui：UI界面
* spring-boot-admin-server-cloud：对Spring Cloud的接入

```xml
<project>
    <!-- 模块名及描述信息 -->
    <name>commerce-admin</name>
    <description>监控服务器</description>

    <dependencies>
        <!-- spring cloud alibaba nacos discovery 依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.3.RELEASE</version>
        </dependency>
        <!-- SpringBoot Admin -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.2.0</version>
        </dependency>
        <!-- 开启登录认证功能 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- 实现对 Java Mail 的自动化配置 -->
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-mail</artifactId>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>com.wkq</groupId>
            <artifactId>commerce-mvc-config</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <!--
        SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持，可以将
        SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
     -->
    <build>
        <finalName>${artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
```
#### 添加启动注解：@EnableAdminServer
```java
/**
 * <h1>监控中心服务器启动入口</h1>
 */
@SpringBootApplication
@EnableAdminServer
public class SpringBootAdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAdminApplication.class, args);
    }
}
```
#### 编写bootstrap.yml文件
```yaml
server:
  port: 7001
  servlet:
    context-path: /commerce-admin

spring:
  application:
    name: commerce-admin
  security:
    user:
      name: wkq
      password: 88888888
  cloud:
    nacos:
      discovery:
        enabled: true
        server-addr: 47.94.9.237:8848
        namespace: 95c065b5-6116-4637-b522-c3a7a76c3aeb
        metadata: # 元数据
          management:
            context-path: ${server.servlet.context-path}/actuator
          user.name: wkq
          user.password: 88888888
  thymeleaf:
    check-template: false
    check-template-location: false
  # 被监控的应用状态变更为 DOWN、OFFLINE、UNKNOWN 时, 会自动发出告警: 实例的状态、原因、实例地址等信息
  # 需要在 pom.xml 文件中添加 spring-boot-starter-mail 依赖
  # 配置发送告警的邮箱服务器
  # 但是, 这个要能连接上, 否则会报错
  #  mail:
  #    host: qinyi.imooc.com
  #    username: qinyi@imooc.com
  #    password: QinyiZhang
  #    default-encoding: UTF-8
  # 监控告警通知
#  boot:
#    admin:
#      notify:
#        mail:
#          from: ${spring.mail.username}
#          to: qinyi@imooc.com
#          cc: qinyi@imooc.com

# 暴露端点
management:
  endpoints:
    web:
      exposure:
        include: '*'  # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 *, 可以开放所有端点
  endpoint:
    health:
      show-details: always
```
#### 启动SpringBoot应用
启动 SpringBootAdminApplication 类，打开 http://localhost:7001/commerce-admin, 输入 bootstrap.yaml中设置的用户名和密码进行登录。界面如下：<br/>
![](./img/springbootAdmin1.png)<br/>
![](./img/SpringBootAdmin2.png)<br/>
至此，SpringBootAdmin监控服务器搭建成功。

## 应用注册到SpringBootAdminServer
被监控和管理的应用(微服务)，注册到Admin Server的两种方式
#### 方式一
被监控和管理的应用程序，使用SpringBootAdminClient库，通过Http调用注册到SpringBootAdminServer上，微服务架构下不会使用这种方式。
#### 方式二
首先，被监控和管理的应用程序，注册到SpringCloud集成的注册中心；然后SpringBootAdminServer通过注册中心主动地获取到被监控和管理的应用程序。这种方式简单方便。<br/>
在要被监控和管理的应用程序的bootstrap.yaml文件中添加：<br/>
操作步骤如下：<br/>
1. 添加SpringBootActuator依赖

```xml
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
```

2. 暴露SpringBootActuatorEndpoints
```yaml
# 暴露端点
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always
```
3. 指定actuator端点的访问路径

```yaml
spring:
  cloud:
    nacos:
      discovery:
        metadata:
          management:
            context-path: ${server.servlet.context-path}/actuator
```
启动该应用程序的两个进程，然后在SpringBootAdmin控制面板中即可看到被监控和管理的应用程序。<br/>
![](./img/SpringBootAdmin3.png)
![](./img/SpringBootAdmin4.png)


## 监控中心服务器添加安全访问控制
#### 引入依赖
```xml
<!-- 开启登录认证功能 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
```
#### 修改bootstrap.yaml文件，指定用户名和密码
```yaml
spring:
  security:
    user:
      name: wkq
      password: 88888888
```
#### 因为增加了账号和密码，其他需要被监控和管理的应用程序也需要配置账号和密码,所以需要对SpringBootAdmin应用程序做一些额外的配置

```javas
package com.wkq.commerce.conf;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

/**
 * <h1>配置安全认证，以便其它的微服务可以注册</h1>
 * 做安全的过滤配置
 */
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
    /**
     * 应用上下文路径
     */
    private final String adminContextPath;

    public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
        this.adminContextPath = adminServerProperties.getContextPath();
    }

    /**
     * 配置安全认证，以便其他的服务可以注册
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");
        http.authorizeRequests()
                //1.配置所有静态资源和登录也可以公开访问
                .antMatchers(adminContextPath + "/assets/**").permitAll()
                .antMatchers(adminContextPath + "/login").permitAll()
                //2.其他请求，必须要经过认证
                .anyRequest().authenticated()
                .and()
                //3. 配置登录和登出路径
                .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler)
                .and()
                .logout().logoutUrl(adminContextPath + "/logout")
                .and()
                //4.开启http basic支持，其它的服务模块注册是需要使用
                .httpBasic()
                .and()
                //5.开启基于cookie 的CSRF保护
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                //6.忽略这些路径的CSRF保护，以便其他的模块可以实现注册
                .ignoringAntMatchers(adminContextPath + "/instances", adminContextPath + "/actuator/**")
        ;
    }
}
```
#### 重启应用
![](./img/springbootadmin5.png)


## SpringBootAdmin自定义监控报警
### 方式一：邮件
1. 引入依赖
```xml
 <!-- 实现对 Java Mail 的自动化配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
```
2.bootstrap.yaml文件中增加配置
```yaml
#   被监控的应用状态变更为 DOWN、OFFLINE、UNKNOWN 时, 会自动发出告警: 实例的状态、原因、实例地址等信息
#   需要在 pom.xml 文件中添加 spring-boot-starter-mail 依赖
#   配置发送告警的邮箱服务器
#   但是, 这个要能连接上, 否则会报错
#  mail:
#      host: qinyi.imooc.com
#      username: qinyi@imooc.com
#      password: QinyiZhang
#      default-encoding: UTF-8
#   监控告警通知
#  boot:
#    admin:
#      notify:
#        mail:
#          from: ${spring.mail.username}
#          to: qinyi@imooc.com
#          cc: qinyi@imooc.com
```
### 方式二
通过实现AbstractEventNotifier这个事件通知器的抽象基类实现


:::tip
<P>SpringBootAdmin是一个简单的组件，只是对SpringBootActuator进行了封装和解析，在使用和接入上面并不需要我们做太多的工作，但这不影响它提供的便捷的监控效果，所以SpringBootAdmin的应用领域较为广泛。</P>
:::
